package hello.app;

import hello.app.component.ListItem;
import hello.app.component.ListItemAdapter;
import hello.app.dialog.ChangeEvaluationBuilder;
import hello.app.dialog.CommentBuilder;
import hello.app.dialog.CommentEvaluationBuilder;
import hello.app.dialog.ProgressDialogEx;
import hello.app.model.CommentModel;
import hello.app.model.HelloApi;
import hello.app.model.HelloContactModel;
import hello.app.model.HelloSetting;
import hello.app.model.ModelManager;
import hello.app.model.data.Comment;
import hello.app.model.data.HelloContact;
import hello.app.util.AdteAsyncTask;
import hello.app.util.Debug;
import hello.app.util.ErrorDialogBuilder;
import hello.app.util.ThreadUtil;
import hello.app.util.Util;
import hello.app.util.AdteAsyncTask.BackgroundRunner;
import hello.app.util.AdteAsyncTask.FinishRunner;
import hello.app.util.ThreadUtil.Runner;

import java.util.ArrayList;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class ContactActivity extends Activity implements OnItemClickListener, CommentBuilder.onSavedCommentListener, CommentEvaluationBuilder.OnFinishListener{
	private static final int UNKNOWN_ERROR = 1;
	private static final int HELLO_API_ERROR = 2;

	private static final int MENU_ID_COMMET = (Menu.FIRST + 1);
	private static final int MENU_ID_CHANGE_EVALUATION = (Menu.FIRST + 2);

	private final int FP = ViewGroup.LayoutParams.FILL_PARENT;

	private int mAddCommetPostion = 0;
	private int mMyCommetPostion = -1;
	HelloContactModel mContactModel;
	CommentModel mCommentModel;
	HelloSetting mHelloSetting;
	HelloContact mContact;
	ModelManager mManager;
	ListView mInfoListView;
	Comment[] mComments;

	private final static int CHANGE_EVALUATION = 0;

	public static void startContactActivity(Context context, HelloContact contact){
		Intent in = new Intent(context,ContactActivity.class);
		in.putExtra("contact", contact);
		context.startActivity(in);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.contact);
		mManager = ModelManager.getInstatce(this);
		mContactModel = mManager.getHelloContactModel();
		mCommentModel = mManager.getCommentModel();
		mHelloSetting =  mManager.getHelloSetting();
		mInfoListView = (ListView)findViewById(R.id.infoListView);

		Bundle extras = getIntent().getExtras();
		int contact_id = 0;
		if(extras != null){
			HelloContact contact = (HelloContact) extras.getSerializable("contact");
			contact_id = (int) contact.getId();
			if(contact_id == 0){
				//ローカルにデータがない場合の処理
				//着信履歴にもともと登録されているものなので、サーバーからとってくる
				HelloApi api = mManager.getHelloApi();
				try {
					HelloContact data = api.getContact(contact.getPhone());
					if(Util.isSet(contact.getName())){
	        			data.setName(contact.getName());
	        		}
					mContactModel.save(data);
					initView(data);
				} catch (Exception e) {
					showDialog(HELLO_API_ERROR);
				}
			}else{
				initView(mContactModel.findById(contact_id));
			}
		}else{
			showDialog(UNKNOWN_ERROR);
		}
	}
	@Override
	protected Dialog onCreateDialog(int id) {
		ErrorDialogBuilder builder;
		switch (id) {
		case HELLO_API_ERROR:
			builder = new ErrorDialogBuilder(this, Application.TITLE, getString(R.string.error_network));
			builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					ContactActivity.this.finish();
				}
			});
			return builder.create();
		case UNKNOWN_ERROR:
			builder = new ErrorDialogBuilder(this, Application.TITLE, getString(R.string.error_unknown));
			builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					ContactActivity.this.finish();
				}
			});
			return builder.create();
		default:
			return null;
		}
	}

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // メニューアイテムを追加します
        menu.add(Menu.NONE, MENU_ID_COMMET, Menu.NONE, getString(R.string.contact_comment));
        menu.add(Menu.NONE, MENU_ID_CHANGE_EVALUATION, Menu.NONE, getString(R.string.contact_change_evaluation));

        return super.onCreateOptionsMenu(menu);
    }

	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        boolean ret = true;
        switch (item.getItemId()) {
        default:
            ret = super.onOptionsItemSelected(item);
            break;
        case MENU_ID_COMMET:
        	showCommentDlg();
        	break;
        case MENU_ID_CHANGE_EVALUATION:
        	showChangeEvaluationDlg();
        	break;
        }
        return ret;
    }

	/**
	 * 口コミ保存時
	 */
	public void onSaved(String text) {
		ProgressDialogEx dlg = new ProgressDialogEx(this,
				"口コミを保存中です。しばらくお待ちください");
		AdteAsyncTask task = new AdteAsyncTask(new BackgroundRunner() {
			public Object exec(Object... args) {
				String text = (String) args[0];
				HelloApi api = mManager.getHelloApi();
				boolean ret = false;
				try {
					Comment cmt = api.saveComment(mContact.getId(), text);
					mCommentModel.save(cmt);
					ret = true;
				} catch (Exception e) {
					Debug.error(e.getMessage());
					ret = false;
				}
				return ret;
			}
		}, new FinishRunner() {
			public void onFinish(Object success) {
				if ((Boolean)success) {
					initView(mContact);
					Toast.makeText(ContactActivity.this, "口コミを保存しました",
							Toast.LENGTH_LONG).show();
				} else {
					Toast.makeText(ContactActivity.this,
							"口コミを保存ができませんでした。ネットワークに繋がっているか確認してください",
							Toast.LENGTH_LONG).show();
				}
			}
		}, (ProgressDialog) dlg);

		// 非同期(スレッド)処理の実行
		task.execute(text);
	}

	/**
	 * 口コミ評価の終了時のリスナー
	 */
	public void onFinished(boolean success) {
		if(success){
			Toast.makeText(ContactActivity.this, "評価しました。", Toast.LENGTH_SHORT).show();
			initView(mContact);
		}else{
			Toast.makeText(ContactActivity.this, "評価に失敗しました。ネットワークに繋がっているか確認してください", Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * リストクリック時動作
	 */
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		if(position == CHANGE_EVALUATION){
			showChangeEvaluationDlg();
		}else if(position == mAddCommetPostion || position == mMyCommetPostion){
			//自分のコメントかコメント追加のアイテムだった場合
			showCommentDlg();
		}else{
			if(mComments.length > position - 1){
				showEvaluateCommetDlg(mComments[position - 1]);
			}
		}
	}

	private void initView(HelloContact contact){
		StringBuilder sb = new StringBuilder();
		mContact = contact;
		sb.append("名前 : ").append(mContact.getName()).append("\n");
		sb.append("住所 : ").append(mContact.getAddress()).append("\n");
		sb.append("業種 : ").append(mContact.getType()).append("\n");
		sb.append("評価 : ").append(String.format("%s:%d %s:%d ",getString(R.string.good), mContact.getGood(), getString(R.string.bad), mContact.getBad())).append("\n");
		sb.append("評価状態 : ").append(mContact.getEvaluatedString());

		mMyCommetPostion = -1;	//初期化
		mComments = getComment();
		ArrayList<ListItem> ListItems = new ArrayList<ListItem>();
		ListItems.add(new ListItem("詳細情報",sb.toString()));
		for(Comment cmt : mComments){
			String col = cmt.getUserId() == mHelloSetting.getUserId() ? "-あなたの口コミ-" : String.format("-誰着%dさんの口コミ-",cmt.getUserId());
			ListItems.add(new ListItem(col,cmt.getText()+"\n"+String.format("%s:%d %s:%d ",getString(R.string.good), cmt.getGood(), getString(R.string.bad), cmt.getBad())));
			if(cmt.getUserId() == mHelloSetting.getUserId()){
				mMyCommetPostion = ListItems.size() - 1;	//自分のコメントの場所を記憶
			}
		}

		ListItems.add(new ListItem("操作","このコンタクトに口コミする"));
		mAddCommetPostion = ListItems.size() - 1;

		ListItemAdapter listAdapter = new ListItemAdapter(this, R.layout.contact_row, ListItems);

		mInfoListView.setAdapter(listAdapter);
		mInfoListView.setLayoutParams(createParam(FP,FP));
		mInfoListView.setOnItemClickListener(this);
		mInfoListView.invalidateViews();
	}

	private void showEvaluateCommetDlg(Comment comment){
		CommentEvaluationBuilder builder = new CommentEvaluationBuilder(this, comment);
		builder.setOnFinishListener(this);
    	builder.create().show();
	}

	private void showCommentDlg(){
		Comment cmt = mCommentModel.findUnique(mContact.getId(), mManager.getHelloSetting().getUserId());
    	String org = cmt != null ? cmt.getText() : "";
    	CommentBuilder builder = new CommentBuilder(this, org);
    	builder.setOnSavedCommentListener(this);
    	builder.create().show();
	}

	private void showChangeEvaluationDlg(){
		if(mContact.getEvaluated() != HelloContact.NON_EVALUATATION){
			final ChangeEvaluationBuilder builder = new ChangeEvaluationBuilder(ContactActivity.this);
			builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						HelloApi api = mManager.getHelloApi();
						try {
							mContact = api.changeCount(String.valueOf(mContact.getId()));
							Debug.log("Call changeCount");
							HelloContactModel model = ModelManager.getInstatce(ContactActivity.this).getHelloContactModel();
							//ローカルにある名前を優先する
							mContact = Util.protectContactName(model, mContact);
							model.save(mContact);
							Toast.makeText(ContactActivity.this, "評価を変更しました", Toast.LENGTH_LONG).show();
							initView(mContact);
						}
						catch (Exception e) {
							Toast.makeText(ContactActivity.this, "評価を変更に失敗しました", Toast.LENGTH_LONG).show();
							Debug.error(e.getMessage());
						}finally{
							dialog.cancel();
						}
					}
			});
			builder.create().show();
		}else{
			//評価後画面を更新する必要があるため
			OnCancelListener listener = new OnCancelListener() {
				public void onCancel(DialogInterface dialog) {
					HelloContact old = mContact;
					mContact = mContactModel.findById(mContact.getId());
					if(mContact.getEvaluated() != old.getEvaluated()){
						initView(mContact);
					}
				}
			};
			EvaluationActicity.start(mContact, ContactActivity.this, listener);
		}
	}

	private Comment[] getComment(){
		Comment[] cmts = mCommentModel.findByContactId(mContact.getId());
		(new ThreadUtil(new Runner() {
			public void exec(Object... args) {
				//int length = (Integer)args[0];
				try {
					Comment[] cmts = mManager.getHelloApi().getComments(mContact.getId());
					for(Comment cmt : cmts){
						mCommentModel.save(cmt);
					}
					/*if(cmts.length != length){
						initView(mContact);
					}*/
				} catch (Exception e) {
					Debug.error(e.getMessage());
				}

			}
		})).start();
		return cmts;
	}

	/**
	* 幅と高さを指定したLinearLayout.LayoutParamsクラスを作成して返す
	* @param width
	* @param height
	* @return
	*/
	private LinearLayout.LayoutParams createParam(int width, int height){
		return new LinearLayout.LayoutParams(width, height);
	}
}
